//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Eic.h"
#include "stdio.h"
#include "MTAG_CtrlStd.h"
#include "uGererFormatRTF.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#define MODULE_TAG MTAG_UGERERFORMATRTF
/*******************************************************************************

Fonction :

Paramètres d'entrée :

Paramètres de sortie :

Valeur retournée :
*******************************************************************************/
__fastcall TGererFormatRTF::TGererFormatRTF()
{
const char* szNomSection[NB_NOM_SECTION] = {"",
                                            "\\header","\\headerr","\\headerl","\\headerf",
                                            "\\footer","\\footerr","\\footerl","\\footerf",
                                            "",
                                            "\\pard","\\fonttbl","\\filetbl","\\colortbl","\\stylesheet","\\listtables",
                                            "\\revtbl","\\rsidtable","\\*\\generator"};
for (int i=0 ; i<NB_NOM_SECTION ; i++)
   aNomSection[i] = szNomSection[i];
}
//---------------------------------------------------------------------------
void __fastcall TGererFormatRTF::CreerUnRTFPourUneSection(const AnsiString &aRTFSource,NOM_SECTION eNomSection, AnsiString *aRTFCible)
{
  int shNiv = 0;
  int i;
  try
  {
    i=1;
    if (eNomSection == CORPS)
      i = aRTFSource.Length();
    *aRTFCible = aRTFSource;
    if (i != aRTFSource.Length() && aRTFSource.Length())
    {
      switch(eNomSection)
      {
        case PIED_DE_PAGE       : SupprimerSection(EN_TETE,      aRTFCible); break;
        case PIED_DE_PAGE_RIGHT : SupprimerSection(EN_TETE_RIGHT,aRTFCible); break;
        case PIED_DE_PAGE_LEFT  : SupprimerSection(EN_TETE_LEFT, aRTFCible); break;
        case PIED_DE_PAGE_FRONT : SupprimerSection(EN_TETE_FRONT,aRTFCible); break;
      }
      do
      {
        if (((*aRTFCible)[i] == '{' ) && (i == 1 || (*aRTFCible)[i-1] != '\\'))
          shNiv++;
        //SI nous sommes sur un paramètre de 2ème niveau
        if (shNiv == 2 && /*aRTFSource*/(*aRTFCible)[i] == '\\')
        {
           //SI le caractère courant correspond au début de la section recherchée
           if (OnEstSurMotCle(aRTFCible->c_str(), i-1, aNomSection[eNomSection]))
             break;
        }
        if (((*aRTFCible)[i] == '}') && (i == 1 || (*aRTFCible)[i-1] != '\\'))
          shNiv--;
        i++;
      }
      //TANT que nous n'avons pas fini de scruter la chaine
      //ET QUE nous sommes dans le premier "paragraphe" du RTF
      while (i<(*aRTFCible).Length() && shNiv != 0);
      RemonterSection(eNomSection,aRTFCible,i);
    }
    else if (eNomSection == CORPS)
    {
      SupprimerSection(EN_TETE,            aRTFCible);
      SupprimerSection(PIED_DE_PAGE,       aRTFCible);

      SupprimerSection(EN_TETE_RIGHT,      aRTFCible);
      SupprimerSection(PIED_DE_PAGE_RIGHT, aRTFCible);

      SupprimerSection(EN_TETE_LEFT,       aRTFCible);
      SupprimerSection(PIED_DE_PAGE_LEFT,  aRTFCible);

      SupprimerSection(EN_TETE_FRONT,      aRTFCible);
      SupprimerSection(PIED_DE_PAGE_FRONT, aRTFCible);
    }
    if (i == aRTFSource.Length())
      *aRTFCible = EmptyStr;
  }
  catch (Exception &e)
  {
    EICDisplayException(TAGL,e);
  }
}

//---------------------------------------------------------------------------
void __fastcall TGererFormatRTF::RemonterSection(NOM_SECTION eNomSection, AnsiString *aRTFCible, int Index)
{
  int nbOuvrant = 0;
  int Index1;
  try
  {
    if (OnEstSurMotCle(aRTFCible->c_str(), Index-1, aNomSection[eNomSection]))
    {
      //On supprime le mot clé de la section à remonter
      if ((Index > 1 && (*aRTFCible)[Index-2] != '\\') || (Index == 2))
        aRTFCible->Delete(Index, aNomSection[eNomSection].Length());
      //Il faut ensuite aller supprimer le '{' de début de section.
      Index1 = Index;
      while (Index1 >= 1)
      {
        if (((*aRTFCible)[Index1] == '{') && (Index1 == 1 || (*aRTFCible)[Index1-1] != '\\'))
          {
            aRTFCible->Delete(Index1,1);
            break;
          }
        Index1--;
      }

     do
      {
      if (((*aRTFCible)[Index] == '{') && (Index == 1 || (*aRTFCible)[Index-1] != '\\'))
        nbOuvrant++;
      else if (((*aRTFCible)[Index] == '}') && (Index == 1 || (*aRTFCible)[Index-1] != '\\'))
        nbOuvrant--;
      Index++;
      }
      //TANT que nous n'avons pas fini de scruter la chaine
      //ET QUE nous sommes dans le premier "paragraphe" du RTF
      while (Index <= aRTFCible->Length() && nbOuvrant >= 0);
      //Suppression de tout ce qui suit la section remontée
      //Puis aller supprimer le '}' de fin de section.
      aRTFCible->Delete(Index-1, aRTFCible->Length() - aRTFCible->SubString(1,Index -1).Length() );
    }
  }
  catch (Exception &e)
  {
    EICDisplayException(TAGL,e);
  }
}

//---------------------------------------------------------------------------
int __fastcall TGererFormatRTF::SupprimerSection(NOM_SECTION eNomSection, AnsiString *aRTFCible)
{
  int shNiv = 0,NbOuvrant = 0;
  int i,iDebutSection = -2;
  char *szRTFCible = new char [aRTFCible->Length()+1];
  try
  {
   i=0;
   strcpy(szRTFCible,aRTFCible->c_str());
   do
      {
      if ((szRTFCible[i] == '{') && (i == 0 || szRTFCible[i-1] != '\\'))
        shNiv++;
      if (szRTFCible[i] == '\\')
         {
         //SI le caractère courant correspond au début d'une section recherchée
         if (OnEstSurMotCle(szRTFCible, i, aNomSection[eNomSection]))
         {
            //Rechercher la fin de section afin de la supprimer
            int iApresSection = i;
            do
            {
              if ((szRTFCible[iApresSection] == '{') && (i == 0 || szRTFCible[i-1] != '\\'))
                NbOuvrant++;
              else if ((szRTFCible[iApresSection] == '}') && (i == 0 || szRTFCible[i-1] != '\\'))
                NbOuvrant--;
              iApresSection++;
            }
            //TANT que nous n'avons pas fini de scruter la chaine
            //ET QUE nous sommes dans le premier "paragraphe" du RTF
            while (szRTFCible[iApresSection] != '\0' && NbOuvrant >= 0);
            //Suppression de la section
            //Il faut aller supprimer depuis le '{' de début de section jusqu'à la fin
            iDebutSection = i;
            while (iDebutSection >= 1)
            {
              if ((szRTFCible[iDebutSection] == '{') && (iDebutSection == 0 || szRTFCible[iDebutSection-1] != '\\'))
                break;
              iDebutSection--;
            }
//            sprintf(&szRTFCible[iDebutSection], "%s", &szRTFCible[iApresSection]);
            strcpy(&szRTFCible[iDebutSection], &szRTFCible[iApresSection]);
            i --;
            NbOuvrant =0;
          }
      }
      //if (!AnsiString(szRTFCible)/*.Trim()*/.IsEmpty())
      //{
        if ((szRTFCible[i] == '}') && (i == 0 || szRTFCible[i-1] != '\\'))
          shNiv--;
      //}
      //else
      //  break;
      i++;
      }
      //TANT que nous n'avons pas fini de scruter la chaine
      //ET QUE nous sommes dans le premier "paragraphe" du RTF
      while (szRTFCible[i] != '\0' && shNiv != 0);
   }
   catch (Exception &e)
   {
    EICDisplayException(TAGL,e);
    iDebutSection = aRTFCible->Length();
   }
   *aRTFCible =  AnsiString(szRTFCible);
   delete []szRTFCible;
   return iDebutSection+1;//+1 car on parle d'une AnsiString
}
//---------------------------------------------------------------------------
void __fastcall TGererFormatRTF::EnregistrerSection(AnsiString *aRTFCible,
                                                    NOM_SECTION eNomSection,
                                                    AnsiString aRTF_A_Ajouter)
{
  AnsiString TexteSection;
  int iPosInsertionSection;
  TStringList *ListeFont = NULL;
  TList *lstCouleurs = NULL;

  try
  {
    ListeFont = new TStringList;
    lstCouleurs = new TList;
    FusionnerTables(aRTFCible, ListeFont, lstCouleurs, true);
    FusionnerTables(&aRTF_A_Ajouter, ListeFont, lstCouleurs, false);
    RemplacerTables(aRTFCible, ListeFont, lstCouleurs);
    //On supprime la section à enregistrer du rtf cible
    SupprimerSection(eNomSection, aRTFCible);

    if (aRTF_A_Ajouter.IsEmpty())
       return;
    //Récupérer uniquement la section qui nous intéresse dans le rtf à ajouter
    ExtraireSection(aRTF_A_Ajouter,&TexteSection);
    //Ajouter cette section au rtf cible
    iPosInsertionSection = PositionnerApresSectionEntete(*aRTFCible);
    aRTFCible->Insert("{"+ aNomSection[eNomSection] + TexteSection + "}", iPosInsertionSection);
  }
  catch (Exception &e)
  {
    EICDisplayException(TAGL,e);
  }
 delete lstCouleurs;           lstCouleurs = NULL;
 delete ListeFont;
}

//---------------------------------------------------------------------------
void __fastcall TGererFormatRTF::ExtraireSection(const AnsiString &aRTF_A_Ajouter, AnsiString *TexteSection)
{
  int shNiv = 0,NbOuvrant = 0, i;
  AnsiString TexteComplet;
  char *szTexte = new char[aRTF_A_Ajouter.Length()+1];
  char *szTexteSection = new char[aRTF_A_Ajouter.Length()+1];
  try
  {
    i=0;
    strcpy(szTexte,aRTF_A_Ajouter.c_str());
    //TexteComplet =  aRTF_A_Ajouter;
    //Le texte de la section correspond à ce qui suit /pard/plain au niveau 1
    do
      {
      if ((szTexte[i] == '{') && (i == 0 || szTexte[i-1] != '\\' ))
        shNiv++;

      //SI nous sommes sur un paramètre de 2ème niveau
      if (shNiv == 1 && szTexte[i] == '\\')
      {
         //SI le caractère courant correspond au début de la section recherchée
         if (OnEstSurMotCle(szTexte, i, aNomSection[PARD_PLAIN]))
         {
          int iDebut = i;
           do
            {
            if ((szTexte[i] == '{') && (i == 0 || szTexte[i-1] != '\\'))
              NbOuvrant++;
            else if ((szTexte[i] == '}') && (i == 0 || szTexte[i-1] != '\\'))
              NbOuvrant--;
            //*TexteSection += szTexte[i];
            i++;
            }
            //TANT que nous n'avons pas fini de scruter la chaine
            //ET QUE nous sommes dans le premier "paragraphe" du RTF
            while (szTexte[i] != '\0'  && NbOuvrant >= 0);
            sprintf(&szTexteSection[0], "%s", &szTexte[iDebut]);
            sprintf(&szTexteSection[i-iDebut-1], "%s", "\0");
            //Suppression de la section
            /*if (TexteSection->Length())
               TexteSection->Delete(TexteSection->Length()-1,2);*/
            break;
         }
      }
      if ((szTexte[i] == '}') && (i == 0 || szTexte[i-1] != '\\'))
        shNiv--;
      i++;
      }
      //TANT que nous n'avons pas fini de scruter la chaine
      //ET QUE nous sommes dans le premier "paragraphe" du RTF
      while (szTexte[i] != '\0'  && shNiv != 0);
   }
   catch (Exception &e)
   {
    EICDisplayException(TAGL,e);
   }
   *TexteSection = szTexteSection;
   delete []szTexte;
   delete []szTexteSection;
}
//---------------------------------------------------------------------------
int __fastcall TGererFormatRTF::PositionnerApresSectionEntete(const AnsiString &aRTFSource)
{
  int shNiv = 0,NbOuvrant = 0;
  int i, iFin = 0;
  try
  {
   //On se positionne au début de la section \ColorTbl
   for (i=1 ; i<aRTFSource.Length() && (shNiv != 2 || !OnEstSurMotCle(aRTFSource.c_str(), i-1, aNomSection[COLORTBL])) ; i++)
      {
      if ((aRTFSource[i] == '{') && (i == 1 || aRTFSource[i-1] != '\\'))
        shNiv++;
      else if ((aRTFSource[i] == '}') && (i == 1 || aRTFSource[i-1] != '\\'))
        shNiv--;
      }

   //SI la section ColorTbl n'existe pas
   if (i == aRTFSource.Length())
      {
      shNiv = 0;
      //On se positionne au début de la section \FontTbl
      for (i=1 ; i<aRTFSource.Length() && (shNiv != 2 || !OnEstSurMotCle(aRTFSource.c_str(), i-1, aNomSection[FONTTBL])) ; i++)
         {
         if ((aRTFSource[i] == '{') && (i == 1 || aRTFSource[i-1] != '\\'))
           shNiv++;
         else if ((aRTFSource[i] == '}') && (i == 1 || aRTFSource[i-1] != '\\'))
           shNiv--;
         }
      }

   //SI le début a été trouvé, on va à la fin
   if (i < aRTFSource.Length())
      {
      do
         {
         if ((aRTFSource[i] == '{') && (i == 1 || aRTFSource[i-1] != '\\'))
           NbOuvrant++;
         else if ((aRTFSource[i] == '}') && (i == 1 || aRTFSource[i-1] != '\\'))
           NbOuvrant--;
         i++;
         }
         //TANT que nous n'avons pas fini de scruter la chaine
         //ET QUE nous sommes dans le premier "paragraphe" du RTF
         while (i<=aRTFSource.Length() && NbOuvrant >= 0);
      }

   iFin = min(i, aRTFSource.Length());
   }
   catch (Exception &e)
   {
    EICDisplayException(TAGL,e);
   }
   return iFin;
}
/*******************************************************************************

Fonction :

Paramètres d'entrée :

Paramètres de sortie :

Valeur retournée :
*******************************************************************************/
void __fastcall TGererFormatRTF::FusionnerTables(AnsiString *aRTF_A_Analyser,
                                                 TStringList *ListeFont,
                                                 TList *lstCouleurs,
                                                 bool bStocker)
{
  int NbOuvrant = 0;
  int i = 0, DebutPolice = 1, Index = 0, NoOrdre = 0;
  int iDebut, iFin;
  char *szTexte = new char[aRTF_A_Analyser->Length()+1];
  char *szBuffer = NULL;
  AnsiString aBuffer;
  bool Modification = false;
  int iRouge, iVert, iBleu;
  try
  {
    strcpy(szTexte, aRTF_A_Analyser->c_str());

    //On se place au début de la zone FontTbl
    for (i = 0 ; !OnEstSurMotCle(szTexte, i, aNomSection[FONTTBL]) && szTexte[i] != '\0' ; i++);

    // Listages des polices utilisées dans  le RTF (recensée dans la section FontTbl)
    ////////////////////////////////////////////////////////////////////////////
    if (szTexte[i] != '\0')
      {
      NbOuvrant++;
      PositionnerApresMotCle(szTexte, &i);
      NoOrdre = 0;
      do
        {
        if ((szTexte[i] == '{') && (i == 0 || szTexte[i-1] != '\\'))
          {
          NbOuvrant++;
          PositionnerApresMotCle(szTexte, &i);
          PositionnerApresMotCle(szTexte, &i);
          DebutPolice = i+1;
          }
        else if ((szTexte[i] == '}') && (i == 0 || szTexte[i-1] != '\\'))
          {
          aBuffer = aRTF_A_Analyser->SubString(DebutPolice, ((i+2)-DebutPolice));

          if (!aBuffer.IsEmpty())
             {
             ASSERT(!aBuffer.Trim().IsEmpty()); //Il serait anormal que le nom de la police soit vide

             if (bStocker)
               ListeFont->Add(aBuffer);
             else
               {
               Index = ListeFont->IndexOf(aBuffer);
               if (Index!=-1)
                 {
                 if (NoOrdre!=Index)
                   {
                   RemplacerNumeroFonte(aRTF_A_Analyser, NoOrdre, Index, &i);
                   Modification = true;
                   }
                 }
               else
                 {
                 ListeFont->Add(aBuffer);
                 if(NoOrdre != ListeFont->Count)
                   {
                   RemplacerNumeroFonte(aRTF_A_Analyser, NoOrdre, (ListeFont->Count-1), &i);
                   Modification = true;
                   }
                 }
               if(Modification)
                 {
                 delete []szTexte;
                 szTexte = new char[aRTF_A_Analyser->Length()+1];
                 strcpy(szTexte,aRTF_A_Analyser->c_str());
                 Modification = false;
                 }
               }
             DebutPolice = 0;
             NoOrdre ++;
             }
          NbOuvrant--;
          }
        i++;
        }while (NbOuvrant > 0 && szTexte[i] != '\0');
      }

    //On se place au début de la zone ColorTbl
    for (i=0 ; !OnEstSurMotCle(szTexte, i, aNomSection[COLORTBL]) && szTexte[i] != '\0' ; i++);

    // Listages des couleurs utilisées et éventuellement, modification de leur numéro
    ////////////////////////////////////////////////////////////////////////////
    //Si la table des couleurs a été trouvée
    if (szTexte[i] != '\0')
      {
      PositionnerApresMotCle(szTexte, &i);
      NoOrdre = 1; //La première couleur trouvée est la numéro 1
      iDebut = i;
      while (szTexte[i] != '}' && szTexte[i] != '\0')
        {
        //SI nous sommes sur le séparateur de couleur => "décrypter" celle qui vient d'être lue
        if (szTexte[i] == ';')
           {
           szBuffer = new char[i-iDebut+1];
           strncpy(szBuffer, &szTexte[iDebut], i-iDebut);
           szBuffer[i-iDebut] = '\0';

           sscanf(szBuffer, "\\red%d\\green%d\\blue%d", &iRouge, &iVert, &iBleu);

           if ((Index = lstCouleurs->IndexOf((void*)RGB(iRouge, iVert, iBleu))) == -1)
              Index = lstCouleurs->Add((void*)RGB(iRouge, iVert, iBleu));

           //Si nous ne faisons pas que lister les couleurs et si son numéro a changé
           // => Modifier son numéro dans le texte RTF
           if (!bStocker && NoOrdre != Index+1)
              RemplacerParCouleurTmp(aRTF_A_Analyser, NoOrdre, Index+1);

           delete []szBuffer;        szBuffer = NULL;
           iDebut = i+1; //Début de la prochaine couleur après le ;
           NoOrdre++;
           }

        i++;
        }
      }

   if(!bStocker)
      NettoyerSection(*aRTF_A_Analyser);
   }
   catch (Exception &e)
    {
    EICDisplayException(TAGL,e);
    }
   delete []szTexte;
}

/*******************************************************************************
void __fastcall TGererFormatRTF::RemplacerNumeroFonte(AnsiString *aRTF_A_Analyser,
                                                      int AncienNumero,
                                                      int NouveauNumero,
                                                      int *iPos)

Fonction : Modifie les numéros de fonte. Attention, le nouveau numéro est précédé du caractère "*".

Paramètres d'entrée :

Paramètres modifiés :

Valeur retournée :
*******************************************************************************/
void __fastcall TGererFormatRTF::RemplacerNumeroFonte(AnsiString *aRTF_A_Analyser,
                                                      int AncienNumero,
                                                      int NouveauNumero,
                                                      int *iPos)
{
  int Indice, IndiceDebut, i = 0, iLongueurDepart;
  AnsiString aSection;
  try
    {
    aSection = AnsiString("\\f") + AncienNumero;
    do
      {
      i++;
      if(OnEstSurMotCle(aRTF_A_Analyser->c_str(), i, aSection))
        {
        i = i + aSection.Length();
        IndiceDebut = i;
        iLongueurDepart = aRTF_A_Analyser->Length();
        i = i + AnsiString(AncienNumero).Length();
        aRTF_A_Analyser->Delete(IndiceDebut, (i-IndiceDebut));
        //On ajoute * + Nouveau numéro => Le * est temporaire, il sert à indiquer que la fonte a été remplacée
        aRTF_A_Analyser->Insert(AnsiString("*") + NouveauNumero, IndiceDebut);

        if((*iPos > IndiceDebut) && (iLongueurDepart != aRTF_A_Analyser->Length()))
          (*iPos) = (*iPos) + aRTF_A_Analyser->Length() - iLongueurDepart;
        }
      }
    while( i < aRTF_A_Analyser->Length());

    }
  catch (Exception &e)
    {
    EICDisplayException(TAGL,e);
    }
}
/*******************************************************************************

Fonction :

Paramètres d'entrée :

Paramètres de sortie :

Valeur retournée :
*******************************************************************************/
void __fastcall TGererFormatRTF::RemplacerParCouleurTmp(AnsiString *aRTF, int AncienNumero, int NouveauNumero)
{
  int i;
  AnsiString aCouleur = "\\cf" + AnsiString(AncienNumero);
  try
    {
    for (i=1 ; i<aRTF->Length() ; i++)
       if(OnEstSurMotCle(aRTF->c_str(), i-1, aCouleur))
         {
         aRTF->Delete(i, aCouleur.Length());
         aRTF->Insert("\\cf#tmp" + AnsiString(NouveauNumero), i);
         }
    }
  catch (Exception &e)
    {
    EICDisplayException(TAGL,e);
    }
}
//---------------------------------------------------------------------------
void __fastcall TGererFormatRTF::NettoyerSection(AnsiString &aRTF_A_Analyser)
{
  int Indice, IndiceFin, i = 0;
  try
    {
    do
      {
      i++;
      if(OnEstSurMotCle(aRTF_A_Analyser.c_str(), i-1, "\\f*"))
        aRTF_A_Analyser.Delete(i+2, 1); //Suppression du *
      else if(OnEstSurMotCle(aRTF_A_Analyser.c_str(), i-1, "\\cf#tmp"))
        aRTF_A_Analyser.Delete(i+3, 4); //Suppression du #tmp
      }
    while( i <= aRTF_A_Analyser.Length());

    }
  catch (Exception &e)
    {
    EICDisplayException(TAGL,e);
    }
}
//---------------------------------------------------------------------------

bool __fastcall TGererFormatRTF::OnEstSurMotCle(const char szRtf[],
                                                int iPos,
                                                const AnsiString &aMotCle)

{
  try
    {
    //SI la chaine commence pas le mot clé (Ex:"\margr" => inclure l'anti-slash)
    //ET SI elle achève le RTF
    //   OU SI le caractère qui suit n'est pas une lettre
    //ET SI Elle n'est pas précédé par un anti-slash
    return (strncmpi(&szRtf[iPos], aMotCle.c_str(), aMotCle.Length()) == 0)
         && (szRtf[iPos + aMotCle.Length() + 1] == '\0'
             || UpperCase(szRtf[iPos+aMotCle.Length()]) < 'A'
             || UpperCase(szRtf[iPos+aMotCle.Length()]) > 'Z')
         && (iPos == 0 || szRtf[iPos-1] != '\\');
    }
  catch (Exception &e)
    {
    EICDisplayException(TAGL,e);
    return false;
    }
}
//---------------------------------------------------------------------------

void __fastcall TGererFormatRTF::PositionnerApresMotCle(const char szRtf[], int *iPos)
{
do
   (*iPos)++;
   while(szRtf[*iPos] != '\0' && szRtf[*iPos] != '{' && szRtf[*iPos] != '}' && szRtf[*iPos] != '\\');
}
//---------------------------------------------------------------------------
void __fastcall TGererFormatRTF::RemplacerTables(AnsiString *aRTF, TStringList *ListeFont, TList *lstCouleurs)
{
  AnsiString aChaineAAjouter;
  int i = 0;
  int iPosRemplacement;
  short shRouge, shVert, shBleu;
  try
    {
    //Remplacement de la section fonttbl
    aChaineAAjouter = "{\\fonttbl";
    for(i =0; i < ListeFont->Count; i++)
      aChaineAAjouter = aChaineAAjouter + AnsiString("{\\f") + i + ListeFont->Strings[i];
    aChaineAAjouter = aChaineAAjouter + "}";

    iPosRemplacement = SupprimerSection(FONTTBL, aRTF);
    aRTF->Insert(aChaineAAjouter, iPosRemplacement);

    iPosRemplacement = SupprimerSection(COLORTBL, aRTF);
    //Si la section n'a pas été trouvée
    //On insérera après la section FontTbl
    if (iPosRemplacement == -1)
       iPosRemplacement = PositionnerApresSectionEntete(*aRTF);

    if (lstCouleurs->Count)
       {
       //Remplacement de la section colortbl
       aChaineAAjouter = "{\\colortbl;";
       for(i=0; i < lstCouleurs->Count; i++)
          {
          aChaineAAjouter += "\\red"  +AnsiString(GetRValue((long)lstCouleurs->Items[i]));
          aChaineAAjouter += "\\green"+AnsiString(GetGValue((long)lstCouleurs->Items[i]));
          aChaineAAjouter += "\\blue" +AnsiString(GetBValue((long)lstCouleurs->Items[i]));
          aChaineAAjouter += ";";
          }
       aChaineAAjouter = aChaineAAjouter + "}";

       aRTF->Insert(aChaineAAjouter, iPosRemplacement);
       }
    }
  catch (Exception &e)
    {
    EICDisplayException(TAGL,e);
    }
}
//---------------------------------------------------------------------------
AnsiString __fastcall TGererFormatRTF::ChercherNomPolice(const char szRtf[])
{
  int i = 0, iDebut, iFin;
  char *szMotCle = NULL;
  AnsiString aPolice = EmptyStr;
  short shNiveau = 0;
  try
    {
    //On se positionne sur la section \fonttbl
    for (i=0 ; szRtf[i] != '\0' && !OnEstSurMotCle(szRtf, i,aNomSection[FONTTBL]) ; i++);

    if (szRtf[i] != '\0')
       {
        PositionnerApresMotCle(szRtf, &i);
        i++; //Permet de passer le '{' qui suit \fonttbl
        do
          {
          //On néglige les caractéres ne faisant pas partie des mots clés
          while (szRtf[i] == '{' || szRtf[i] == '}' || shNiveau != 0)
             {
             if (szRtf[i] == '{')
                shNiveau++;
             else if (szRtf[i] == '}')
                shNiveau--;
             i++;
             }

          iDebut = i;
          // Recherche la fin du mot clé
          for (iFin = iDebut;
                  UpperCase(szRtf[iFin+1]) >= 'A' && UpperCase(szRtf[iFin+1]) <= 'Z';
                     iFin++);
          i = iFin+1; //On se positionne après le mot clé
          
          szMotCle = new char[iFin - iDebut + 2];
          strncpy(szMotCle, &szRtf[iDebut], iFin-iDebut+1);
          szMotCle[iFin - iDebut + 1] = '\0';

          if (IsMotCleDeFontTbl(szMotCle))
            {
            //On passe l'éventuel paramétre du mot clé (valeur numérique accolée)
            while (szRtf[i] != '\0' && szRtf[i] != '{' && szRtf[i] != '}' && szRtf[i] != '\\' && szRtf[i] != ' ')
               i++;
            }
          else
             aPolice = aPolice + AnsiString(szMotCle);

          delete []szMotCle;      szMotCle = NULL;
          }
        while(szRtf[i] != '\0' && szRtf[i] != '}' && szRtf[i] != ';');
       }
    }
  catch (Exception &e)
    {
    EICDisplayException(TAGL,e);
    return NULL;
    }
return aPolice.Trim();
}
//---------------------------------------------------------------------------
bool __fastcall TGererFormatRTF::IsMotCleDeFontTbl(const char *NomSection)
{
  const char* szNomSection[] = {"\\f","\\fnil","\\froman","\\fswiss","\\fmodern","\\fscript","\\fdecor","\\ftech",
                         "\\fbidi","\\fcharset","\\fprq","\\ftnil","\\fttruetype","\\cpg"};
  try
    {
    for (int i = 0; i<ARRAYSIZE(szNomSection); i++)
      {
      if(strcmp(NomSection, szNomSection[i]) == 0)
        return true;
      }
    }
  catch (Exception &e)
    {
    EICDisplayException(TAGL,e);
    }
  return false;
}

